<template>
  <div class="cjui-dynamic-form-editor-draw">
    <div v-if="!pageComponents.length" class="page-empty">
      从左侧选择组件拖入
    </div>
    <el-form 
      class="h-full"
      :label-position="baseFormComponent.property.labelPosition"
      :label-width="baseFormComponent.property.labelWidth"
      :size="baseFormComponent.property.size"
    >
      <draggable
        v-model="pageComponents"
        item-key="index"
        group="component"
        filter=".component-toolbar"
        :animation="200"
        :force-fallback="true"
        class="drag-area"
        @change="handleComponentChange"
      >
        <template #item="{ element, index }">
          <el-col
            :span="element.property.__config__.span" 
            :class="['component-form-item', selectedComponentIndex === index && 'is-active']"
            @click="handleComponentSelected(element, index)"
          >
            <el-form-item
              :label="element.property.__config__.label"
              :label-width="element.property.__config__.labelWidth"
            >
              <div class="cjui-dynamic-form-editor-component">
                <component
                  :is="components[element.id]"
                  :property="element.property"
                  :style="{ width: element.property.__config__.width }"
                  readonly
                  v-bind="element.property.__attr__"
                />
              </div>
            </el-form-item>
          </el-col>
        </template>
      </draggable>
    </el-form>
  </div>
</template>

<script lang="ts" setup>
import _ from 'lodash-es'
import draggable from 'vuedraggable'
import { components, DiyComponent } from './components/index'
import {
  FormConfigBaseInfo,
  component as baseInfoComponentRefer,
} from './components/BaseInfo/config'
import {
  FormConfigBaseForm,
  component as baseFormComponentRefer,
} from './components/BaseForm/config'

defineOptions({
  name: 'CjuiDynamicFormEditorDraw',
})

const baseFormComponent = inject<Ref<DiyComponent<FormConfigBaseForm>>>('baseFormComponent')
const pageComponents = inject<Ref<DiyComponent<any>[]>>('pageComponents')
const selectedComponent = inject<Ref<DiyComponent<any>>>('selectedComponent')
const selectedComponentIndex = inject<Ref<number>>('selectedComponentIndex')

/**
 * 选中组件
 * @param component 组件
 * @param index 组件的索引
 */
 const handleComponentSelected = (
  component: DiyComponent<any> | undefined,
  index: number = -1,
) => {
  selectedComponent.value = component
  selectedComponentIndex.value = index
}
// 组件变动（拖拽）
const handleComponentChange = (dragEvent: any) => {
  // 新增，即从组件库拖拽添加组件
  if (dragEvent.added) {
    const { element, newIndex } = dragEvent.added
    handleComponentSelected(element, newIndex)
  } else if (dragEvent.moved) {
    // 拖拽排序
    const { newIndex } = dragEvent.moved
    // 保持选中
    selectedComponentIndex.value = newIndex
  }
}
// 复制组件
const handleCopyComponent = (index: number) => {
  const component = _.cloneDeep(pageComponents.value[index])
  component.uid = new Date().getTime()
  pageComponents.value.splice(index + 1, 0, component)
}
// 删除组件
const handleDeleteComponent = (index: number) => {
  // 删除组件
  pageComponents.value.splice(index, 1)
  if (index < pageComponents.value.length) {
    // 1. 不是最后一个组件时，删除后选中下面的组件
    let bottomIndex = index
    handleComponentSelected(pageComponents.value[bottomIndex], bottomIndex)
  } else if (pageComponents.value.length > 0) {
    // 2. 不是第一个组件时，删除后选中上面的组件
    let topIndex = index - 1
    handleComponentSelected(pageComponents.value[topIndex], topIndex)
  } else {
    // 3. 组件全部删除之后
    handleComponentSelected(undefined, -1)
  }
}
</script>

<style lang="scss">
.cjui-dynamic-form-editor-draw {
  height: 100%;
  position: relative;
  background: #fdfdfd;
  background-image: radial-gradient(#f1f1f1 30%, transparent 0), radial-gradient(#f1f1f1 30%, transparent 0);
  background-size: 30px 30px;
  background-position: 0 0, 15px 15px;

  .page-empty {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
  }

  .drag-area {
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    padding: 10px;
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
    position: relative;
  }

  .el-form {
    .el-form-item__content {
      flex: 1;
    }
  }

  .component-form-item {
    background: #f6f6f6;
    border-color: #f6f6f6;
    border-radius: 5px;
    padding: 8px;
    margin-bottom: 10px;
    cursor: pointer;

    &.is-active {
      background-color: #5ea8f57d;
    }
  }
}

.cjui-dynamic-form-editor-component {
  width: 100%;
}
</style>
